/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.sgf.api.extension;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.util.StdDateFormat;

import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 功能描述: @ClassName: ObjectMapperDateFormatExtend @Author: Fynn Qi @Date: 2019/11/26 15:12 @Version:
 * V1.0
 */
public class ObjectMapperDateFormatExtend extends StdDateFormat {

    private static final long serialVersionUID = 1L;

    private StdDateFormat dateFormat;

    private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";

    private static final String STANDARD_FORMAT1 = "yyyy-MM-dd";

    private SimpleDateFormat extendDateFormat = new SimpleDateFormat(STANDARD_FORMAT);

    private SimpleDateFormat extendDateFormat1 = new SimpleDateFormat(STANDARD_FORMAT1);

    public ObjectMapperDateFormatExtend() {
        ObjectMapper mapper = new ObjectMapper();
        this.dateFormat = (StdDateFormat) mapper.getDeserializationConfig().getDateFormat();
    }

    /**
     * 序列化时会执行这个方法
     *
     * @param date
     * @param toAppendTo
     * @param fieldPosition
     * @return
     */
    @Override
    public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
        return dateFormat.format(date, toAppendTo, fieldPosition);
    }

    /**
     * 反序列化时执行此方法，先执行扩展的DateFormat，如果异常则执执行默认的
     *
     * @param dateStr
     * @return
     * @throws ParseException
     */
    @Override
    public Date parse(String dateStr) throws ParseException {
        Date date;
        try {
            if (this.isLegalDateTime(dateStr, STANDARD_FORMAT)) {
                date = extendDateFormat.parse(dateStr);
            } else if (this.isLegalDate(dateStr, STANDARD_FORMAT1)) {
                date = extendDateFormat1.parse(dateStr);
            } else {
                date = baseParser(dateStr);
            }
        } catch (Exception e) {
            date = baseParser(dateStr);
        }
        return date;
    }

    private boolean isLegalDateTime(String sDate, String dataFormatter) {
        int legalLen = 19;
        if ((sDate == null) || (sDate.length() != legalLen)) {
            return false;
        }

        DateFormat formatter = new SimpleDateFormat(dataFormatter);
        try {
            Date date = formatter.parse(sDate);
            return sDate.equals(formatter.format(date));
        } catch (Exception e) {
            return false;
        }
    }

    private boolean isLegalDate(String sDate, String dataFormatter) {
        int legalLen = 10;
        if ((sDate == null) || (sDate.length() != legalLen)) {
            return false;
        }

        DateFormat formatter = new SimpleDateFormat(dataFormatter);
        try {
            Date date = formatter.parse(sDate);
            return sDate.equals(formatter.format(date));
        } catch (Exception e) {
            return false;
        }
    }

    private Date baseParser(String dateStr) throws ParseException {
        return super.parse(dateStr);
    }

    /**
     * 此方法在ObjectMapper默认的DateFormat里边用到，这里要重写
     *
     * @return
     */
    @Override
    public StdDateFormat clone() {
        StdDateFormat dateFormat = (StdDateFormat) this.dateFormat.clone();
        return new ObjectMapperDateFormatExtend();
    }
}
